package com.dfire.controller;

import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONObject;
import com.dfire.common.entity.HeraAction;
import com.dfire.common.entity.HeraJob;
import com.dfire.common.entity.HeraJobHistory;
import com.dfire.common.entity.model.JsonResponse;
import com.dfire.common.enums.RecordTypeEnum;
import com.dfire.common.enums.RunAuthType;
import com.dfire.common.enums.StatusEnum;
import com.dfire.common.enums.TriggerTypeEnum;
import com.dfire.common.exception.HeraException;
import com.dfire.common.exception.NoPermissionException;
import com.dfire.common.service.HeraJobActionService;
import com.dfire.common.service.HeraJobHistoryService;
import com.dfire.common.service.HeraJobService;
import com.dfire.common.service.HeraUserService;
import com.dfire.common.util.ActionUtil;
import com.dfire.common.util.StringUtil;
import com.dfire.config.UnCheckLogin;
import com.dfire.core.netty.worker.WorkClient;
import com.dfire.logs.MonitorLog;
import com.dfire.protocol.JobExecuteKind;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

/**
 * desc:
 *
 * @author scx
 * @create 2020/06/19
 */
@Controller
@Api("自定义调度中心操作")
@RequestMapping("/cbest/scheduleCenter")
public class CbestScheduleOperatorController extends BaseHeraController {


    private final HeraJobService heraJobService;
    private final HeraJobActionService heraJobActionService;
//    private final HeraGroupService heraGroupService;
    private final HeraJobHistoryService heraJobHistoryService;
    private final HeraUserService heraUserService;
//    private final HeraPermissionService heraPermissionService;
    private final WorkClient workClient;
//
//    private final Set<Long> cancelSet = new HashSet<>();
//    private final HeraJobMonitorService jobMonitorService;

    public CbestScheduleOperatorController(HeraJobActionService heraJobActionService, 
    		@Qualifier("heraJobMemoryService") HeraJobService heraJobService, 
    		  HeraJobHistoryService heraJobHistoryService,
    		  HeraUserService heraUserService, 
    		  WorkClient workClient) {
        this.heraJobActionService = heraJobActionService;
        this.heraJobService = heraJobService;
        this.heraJobHistoryService = heraJobHistoryService;
        this.heraUserService = heraUserService;
        this.workClient = workClient;
    }

   

   

    @RequestMapping(value = "/execute", method = {RequestMethod.GET,RequestMethod.POST})
    @ResponseBody
    @UnCheckLogin
    @ApiOperation("内部调用http外部调用，执行任务")
    public JsonResponse publicExecute(@RequestParam @ApiParam(value = "map参数类型，替换任务的配置信息", required = true) Map<String, String> params) throws ExecutionException, InterruptedException, NoPermissionException, HeraException, TimeoutException {
        String jobIdVal    = params.get("jobId");
        String userNameVal = params.get("userName");
        if (StringUtils.isBlank(jobIdVal)) {
            return new JsonResponse(false, "Parameter missed !!jobId is required");
        }
        if (StringUtils.isBlank(userNameVal)) {
        	return new JsonResponse(false, "Parameter missed !! userName is required");
        }

        HeraAction action = heraJobActionService.findLatestByJobId(Long.parseLong(jobIdVal));
        if (action == null) {
            return new JsonResponse(false, "找不到版本");
        }
        addJobRecord(Integer.parseInt(jobIdVal), "远程执行任务", RecordTypeEnum.REMOTE, getIp() + ":" + userNameVal, String.valueOf(heraUserService.findByName(userNameVal).getId()));
        MonitorLog.info("远程调用:{}", JSONObject.toJSONString(params));
        HeraJob heraJob = heraJobService.findById(Integer.parseInt(jobIdVal));
        Map<String, String> configs = StringUtil.convertStringToMap(heraJob.getConfigs());
        configs.putAll(params);
        heraJob.setConfigs(StringUtil.convertMapToString(configs));
        heraJobService.update(heraJob);
        return execute(action.getId(), 2, userNameVal);
    }


    
    public JsonResponse execute(@JsonSerialize(using = ToStringSerializer.class) @ApiParam(value = "版本id", required = true) Long actionId
            , @ApiParam(value = "触发类型，2手动执行，3手动恢复，6超级恢复", required = true) Integer triggerType,
                                @RequestParam(required = false) @ApiParam(value = "任务执行组", required = false) String execUser) throws InterruptedException, ExecutionException, HeraException, TimeoutException {
        if (actionId == null) {
            return new JsonResponse(false, "请先生成版本再执行");
        }
        if (execUser == null) {
            checkPermission(ActionUtil.getJobId(actionId), RunAuthType.JOB);
        }
        TriggerTypeEnum triggerTypeEnum = TriggerTypeEnum.parser(triggerType);
        if (triggerTypeEnum == null) {
            return new JsonResponse(false, " 无法识别的触发类型，请联系管理员");
        }

        HeraAction heraAction = heraJobActionService.findById(actionId);
        HeraJob heraJob = heraJobService.findById(heraAction.getJobId());
        if (execUser == null) {
            execUser = super.getSsoName();
        }
        if (execUser == null) {
            return new JsonResponse(false, "任务执行人为空");
        }

        String configs = heraJob.getConfigs();
        HeraJobHistory actionHistory = HeraJobHistory.builder().build();
        actionHistory.setJobId(heraAction.getJobId());
        actionHistory.setActionId(heraAction.getId());
        actionHistory.setTriggerType(triggerTypeEnum.getId());
        actionHistory.setOperator(heraJob.getOwner());
        actionHistory.setIllustrate(execUser);
        actionHistory.setStatus(StatusEnum.RUNNING.toString());
        actionHistory.setStatisticEndTime(heraAction.getStatisticEndTime());
        actionHistory.setHostGroupId(heraAction.getHostGroupId());
        heraJobHistoryService.insert(actionHistory);
        heraAction.setScript(heraJob.getScript());
        heraAction.setHistoryId(actionHistory.getId());
        heraAction.setConfigs(configs);
        heraAction.setAuto(heraJob.getAuto());
        heraAction.setHostGroupId(heraJob.getHostGroupId());
        heraJobActionService.update(heraAction);
        workClient.executeJobFromWeb(JobExecuteKind.ExecuteKind.ManualKind, actionHistory.getId());

        String ownerId = getOwnerId();
        if (ownerId == null) {
            ownerId = "0";
        }
        addJobRecord(heraJob.getId(), String.valueOf(actionId), RecordTypeEnum.Execute, execUser, ownerId);
        return new JsonResponse(true, String.valueOf(actionId));
    }

        

 

   

  
   

    

}
